<?php


include_once('Color.php');

abstract class BCGBarcode {
	const COLOR_BG = 0;
	const COLOR_FG = 1;

	protected $error;
	protected $colorFg, $colorBg;
	protected $scale;
	protected $offsetX, $offsetY;

	protected function __construct() {
		$this->setForegroundColor(0x000000);
		$this->setBackgroundColor(0xffffff);
		$this->setScale(1);
		$this->setOffsetX(0);
		$this->setOffsetY(0);

		$this->error = 0;
	}

	public abstract function parse($text);

	public function setForegroundColor($code) {
		if ($code instanceof BCGColor) {
			$this->colorFg = $code;
		} else {
			$this->colorFg = new BCGColor($code);
		}
	}

	public function setBackgroundColor($code) {
		if ($code instanceof BCGColor) {
			$this->colorBg = $code;
		} else {
			$this->colorBg = new BCGColor($code);
		}
	}

	public function setColor($fg, $bg) {
		$this->setForegroundColor($fg);
		$this->setBackgroundColor($bg);
	}

	public function setScale($scale) {
		$scale = intval($scale);
		if ($scale <= 0) {
			$scale = 1;
		}
		$this->scale = $scale;
	}

	public abstract function draw(&$im);

	public function getMaxSize() {
		return array($this->offsetX * $this->scale, $this->offsetY * $this->scale);
	}

	public function setOffsetX($offsetX) {
		$offsetX = intval($offsetX);
		if ($offsetX < 0) {
			$offsetX = 0;
		}
		$this->offsetX = $offsetX;
	}

	public function setOffsetY($offsetY) {
		$offsetY = intval($offsetY);
		if ($offsetY < 0) {
			$offsetY = 0;
		}
		$this->offsetY = $offsetY;
	}

	protected function drawPixel($im, $x, $y, $color = self::COLOR_FG) {
		$xR = ($x + $this->offsetX) * $this->scale;
		$yR = ($y + $this->offsetY) * $this->scale;

		imagefilledrectangle($im,
			$xR,
			$yR,
			$xR + $this->scale - 1,
			$yR + $this->scale - 1,
			$this->getColor($im, $color));
	}

	protected function drawRectangle($im, $x1, $y1, $x2, $y2, $color = self::COLOR_FG) {
		if ($this->scale === 1) {
			imagerectangle($im,
				($x1 + $this->offsetX) * $this->scale,
				($y1 + $this->offsetY) * $this->scale,
				($x2 + $this->offsetX) * $this->scale,
				($y2 + $this->offsetY) * $this->scale,
				$this->getColor($im, $color));
		} else {
			imagefilledrectangle($im, ($x1 + $this->offsetX) * $this->scale, ($y1 + $this->offsetY) * $this->scale, ($x2 + $this->offsetX) * $this->scale + $this->scale - 1, ($y1 + $this->offsetY) * $this->scale + $this->scale - 1, $this->getColor($im, $color));
			imagefilledrectangle($im, ($x1 + $this->offsetX) * $this->scale, ($y1 + $this->offsetY) * $this->scale, ($x1 + $this->offsetX) * $this->scale + $this->scale - 1, ($y2 + $this->offsetY) * $this->scale + $this->scale - 1, $this->getColor($im, $color));
			imagefilledrectangle($im, ($x2 + $this->offsetX) * $this->scale, ($y1 + $this->offsetY) * $this->scale, ($x2 + $this->offsetX) * $this->scale + $this->scale - 1, ($y2 + $this->offsetY) * $this->scale + $this->scale - 1, $this->getColor($im, $color));
			imagefilledrectangle($im, ($x1 + $this->offsetX) * $this->scale, ($y2 + $this->offsetY) * $this->scale, ($x2 + $this->offsetX) * $this->scale + $this->scale - 1, ($y2 + $this->offsetY) * $this->scale + $this->scale - 1, $this->getColor($im, $color));
		}
	}

	protected function drawFilledRectangle($im, $x1, $y1, $x2, $y2, $color = self::COLOR_FG) {
		if ($x1 > $x2) {
			$x1 ^= $x2 ^= $x1 ^= $x2;
		}
		if ($y1 > $y2) {
			$y1 ^= $y2 ^= $y1 ^= $y2;
		}

		imagefilledrectangle($im,
			($x1 + $this->offsetX) * $this->scale,
			($y1 + $this->offsetY) * $this->scale,
			($x2 + $this->offsetX) * $this->scale + $this->scale - 1,
			($y2 + $this->offsetY) * $this->scale + $this->scale - 1,
			$this->getColor($im, $color));
	}

	protected function getColor($im, $color) {
		if ($color === self::COLOR_BG) {
			return $this->colorBg->allocate($im);
		} else {
			return $this->colorFg->allocate($im);
		}
	}

	protected function drawError(&$im, $text) {

		$w = imagesx($im);
		$h = imagesy($im);

		$text = 'Error: ' . $text;

		$width = imagefontwidth(2) * strlen($text);
		$height = imagefontheight(2) + $this->error * 15;
		if ($width > $w || $height > $h) {
			$width = max($w, $width);
			$height = max($h, $height);

			$newimg = imagecreatetruecolor($width, $height);
			imagefill($newimg, 0, 0, imagecolorat($im, 0, 0));
			imagecopy($newimg, $im, 0, 0, 0, 0, $w, $h);
			$im = $newimg;
		}

		imagestring($im, 2, 0, $this->error * 15, $text, $this->colorFg->allocate($im));
		$this->error++;
	}

}
?>